Nakama Runtime Code
サーバーのコードを GoプラグインまたはLuaモジュールとして記述できる
Go
事前にコンパイルが必要。ビルドプロセスは Docker と バイナリで異なる
静的型付けで安全にかける。defer などの便利な構文も使える
オブジェクト指向
Lua
コンパイル不要。modulesフォルダに置いて ロードするだけ
モジュールのロードパス
docker-compose.ymlで実行時のパスを指定できる
data/modulesフォルダー内のファイルをすべてスキャンする
バイナリの場合はフラグで指定 nakama --runtime.path "path/to/data"
.lua, .so拡張子がついたファイルをすべて読み込む
Register RPC
Remote Procedure Call
サーバーサイドで登録した関数を、クライアントサイドから呼び出す。
引数、戻り値は必ず JSONでないとならない
code: .lua
local nk = require("nakama")
local function some_example(context, payload)
local json = nk.json_decode(payload)
nk.logger_info(string.format("Payload: %q", json))
local id = nk.uuid_v4()
nk.leaderboard_create(id, "desc", "best", "0 0 * * 1", json, false)
return nk.json_encode({"id" = id}) end
nk.register_rpc(some_example, "my_unique_id")
Register Hook
RPCと違って、クライアントからは呼び出さない
登録するときは、register_<event>_before/after/~~~ed/endみたいな感じの関数
context
登録されたすべての関数は、contextを引数に取る
コードが実行されるタイミングに依存するフィールドを含む
code: .go
userId, ok := ctx.Value(runtime.RUNTIME_CTX_USER_ID).(string)
if !ok {
// User ID not found in the context.
}
Luaの場合、プロトタイプオブジェクト指向なので直接フィールドにアクセスできる。
Goの場合、Mapオブジェクトなので少し面倒(コンテキストフィールドのキー定数を使ってアクセス)
before/after hook
before hook
context, payload -> new_payload
入力値に前処理を加えることができる
after hook
context, out_comming_payload, in_comming_payload
hookされているハンドラが実行された後に非同期で実行される
入力や出力に影響を与えることは出来ない
Server to Server
HTTP REST handler を作って、呼び出すことができる
呼び出すには、クエリパラメータに http_keyが必要
(defaulthttpkeyがデフォルト)
code: .lua
local nk = require("nakama")
local function http_handler(context, payload)
local message = nk.json_decode(payload)
nk.logger_info(string.format("Message: %q", message))
end
nk.register_rpc(http_handler, "http_handler_path")
v2/rpc/<register_id>で呼び出せる
下のように呼び出した場合、contextの user_id が nil になる
(client からではなくサーバー呼び出し限定にしたい場合は user_id != nil だったらエラーにする)
code: .sh
-d '"{\"some\": \"data\"}"' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json'
Run Once
一回だけ実行するコールバックを登録
多分、サーバー起動時に実行される?
カスタムSQLクエリの実行
サードパーティサービスの登録
code: .lua
nk.run_once(function(context)
-- This is to create a system ID that cannot be used via a client.
nk.sql_exec([[
INSERT INTO users (id, username)
VALUES ($1, $2)
ON CONFLICT (id) DO NOTHING
]], { system_id, "system_id" })
end)
Errors and logs
Goの場合は error or nil を返すハンドリング
Luaの場合は、raise error だが pcall(エラーを起こす可能性のある関数)という、pcall()関数を使ったハンドリングをする
(protected_call)
制限
Lua の version は 5.1
Lua C FFI は使えない。純粋な Lua である必要がある
組み込みLua仮想マシンは、標準ライブラリが制限されている
コードサンドボックスがOSのIO/File Systemを改ざんできないようにするため
Go の version は Nakama Server のリリース時のバージョンによる
Go はすべての標準ライブラリとパッケージを利用できる
Global State
Lua はグローバル変数を使えない
Go はこの制限はなく、グローバル変数を使える
並列実行とアクセス制御は開発者が面倒を見る
例: pokeapi
Server RPC を利用して
Nakama Server から pokeapiにGETリクエストしてそれをクライアントからのRPCで取得できるようにする
(いわゆるproxy)
code: .sh
-H 'authorization: Bearer <session token>'
-d '"{\"PokemonName\": \"dragonite\"}"'
Nakama API Function Ref